package org.kineticsproject.application;

import java.util.ArrayList;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.kineticsproject.application.PopulationNavigationView.TreeObject;


import data.Exercise;
import data.Person;
import data.Population;
import data.DataPackage;
import data.DataFactory;

public class ExerciseNavigationView extends ViewPart implements ISelectionListener  {

	public static final String ID = "org.kineticsproject.application.exerciseNavigationView";
	private TreeViewer viewer;

	class TreeObject {
		private String name;
		private TreeParent parent;
		private Exercise exercise;
		
		public TreeObject(String name) {
			this.name = name;
		}
		public String getName() {
			return name;
		}
		
		public Exercise getExercise() {
			return exercise;
		}
		
		public void setExercise(Exercise exercise)
		{
			this.exercise = exercise;
		}
		
		public void setParent(TreeParent parent) {
			this.parent = parent;
		}
		public TreeParent getParent() {
			return parent;
		}
		public String toString() {
			return getName();
		}
	}
	
	class TreeParent extends TreeObject {
		private ArrayList children;
		public TreeParent(String name) {
			super(name);
			children = new ArrayList();
		}
		public void addChild(TreeObject child) {
			children.add(child);
			child.setParent(this);
		}
		public void removeChild(TreeObject child) {
			children.remove(child);
			child.setParent(null);
		}
		public TreeObject[] getChildren() {
			return (TreeObject[]) children.toArray(new TreeObject[children.size()]);
		}
		public boolean hasChildren() {
			return children.size()>0;
		}
	}

	class ViewContentProvider implements IStructuredContentProvider, 
										   ITreeContentProvider    {

        public void inputChanged(Viewer v, Object oldInput, Object newInput) {
		}
        
		public void dispose() {
			
			// remove PartListener for PopulationNavigation selections
			//getSite().getWorkbenchWindow().getPartService().removePartListener(partListener);
			
		}
        
		public Object[] getElements(Object parent) {
			return getChildren(parent);
		}
        
		public Object getParent(Object child) {
			if (child instanceof TreeObject) {
				return ((TreeObject)child).getParent();
			}
			return null;
		}
        
		public Object[] getChildren(Object parent) {
			if (parent instanceof TreeParent) {
				return ((TreeParent)parent).getChildren();
			}
			return new Object[0];
		}

        public boolean hasChildren(Object parent) {
			if (parent instanceof TreeParent)
				return ((TreeParent)parent).hasChildren();
			return false;
		}


	}
	
	class ViewLabelProvider extends LabelProvider {

		public String getText(Object obj) {
			return obj.toString();
		}
		public Image getImage(Object obj) {
			String imageKey = ISharedImages.IMG_OBJ_ELEMENT;
			if (obj instanceof TreeParent)
			   imageKey = ISharedImages.IMG_OBJ_FOLDER;
			return PlatformUI.getWorkbench().getSharedImages().getImage(imageKey);
		}
	}


    /**
   	 * Create the model of the selected users exercises
     */
    private TreeObject createModel() throws IOException{
    	return createModel(null);
    }
    
    /**
   	 * Create the model of the selected users exercises
     */
    private TreeObject createModel(Person person) throws IOException{
    	   	

		DataPackage dataPackage = DataPackage.eINSTANCE;
		
		//Create new ResourceSet & Resource
		ResourceSet resourceSet = new ResourceSetImpl();
		
		// Register XML resource factory
		resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmi", 
		new XMIResourceFactoryImpl());

		Resource resource = resourceSet.createResource(URI.createFileURI(new File("myPopulation.xmi").getAbsolutePath()));

		// register package in local resource registry
		resourceSet.getPackageRegistry().put(dataPackage.getNsURI(), dataPackage);
		// load resource 
		resource.load(null);
		
	
		Population population = (Population)resource.getContents().get(0);
		
		Iterator<Person> it = population.getPeople().iterator();
    	TreeParent root = new TreeParent("");
    	
    	
    	
		if (it.hasNext())
		{
			Person current;
			
			if (null == person)
			{
				current = it.next();
			} else
			{
				current = person;
			}
			
		
			Iterator<Exercise> itex = current.getExercises().iterator();
			
			while(itex.hasNext())
			{
				Exercise curExercise = itex.next();
	
				TreeObject t = new TreeObject(curExercise.getName());
				t.setExercise(curExercise);
				root.addChild(t);
			}
			
		}
		
        return root;
        
    }

	/**
     * This is a callback that will allow us to create the viewer and initialize
     * it.
     */
	public void createPartControl(Composite parent) {
	
		viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
		viewer.setContentProvider(new ViewContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
		getSite().setSelectionProvider(viewer);
		try {
		viewer.setInput(createModel());
		}
		catch (IOException ioe)
		{
			
		}
		
		// setup PartListener
		//getSite().getWorkbenchWindow().getPartService().addPartListener(partListener);
		
		// setup Person Selection Listener
		getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(this);
		
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
	}
	
	/**
	 * Setup part listener for PopulationNavigation.  When a person is selected
	 * show the exercises that user owns in this view
	 */

	/*private IPartListener partListener = new IPartListener()
	{
		public void partOpened(IWorkbenchPart part){
			trackSelectedPerson(part);
		}
		
		private void trackSelectedPerson(IWorkbenchPart part)
		{
			if (part instanceof PopulationNavigationView)
			{
				PopulationNavigationView popNavView = (PopulationNavigationView) part;
				
			}
		}

		@Override
		public void partActivated(IWorkbenchPart part) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void partBroughtToTop(IWorkbenchPart part) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void partClosed(IWorkbenchPart part) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void partDeactivated(IWorkbenchPart part) {
			// TODO Auto-generated method stub
			
		}


	};
*/
	@Override
	public void selectionChanged(IWorkbenchPart part, ISelection incomingSelection) {
		
		IStructuredSelection selection;
		
		if (incomingSelection instanceof IStructuredSelection)
		{
			selection = (IStructuredSelection) incomingSelection;
			if (1 == selection.size() && selection.getFirstElement() instanceof PopulationNavigationView.TreeObject)
			{
				Person person = ((PopulationNavigationView.TreeObject)selection.getFirstElement()).getPerson();
				try {
					viewer.setInput(createModel(person));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
		
	}


	public void dispose()
	{
		// remove SelectionListener for PopulationNavigation selections
		getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(this);
	}
	

	
	

}

